package com.blueocean_health.care.management.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.blueocean_health.care.management.common.base.em.TimeType;
import com.blueocean_health.care.management.common.base.time.TimeUtils;
import com.blueocean_health.care.management.domain.base.Department;
import com.blueocean_health.care.management.domain.base.SysResult;
import com.blueocean_health.care.management.domain.worktablevo.WorkResultVo;
import com.blueocean_health.care.management.domain.worktablevo.WorkersVo;
import com.blueocean_health.care.management.exception.OrderException;
import com.blueocean_health.care.management.mapper.DepartmentMapper;
import com.blueocean_health.care.management.mapper.NurseWorkerInfoMapper;
import com.blueocean_health.care.management.mapper.OrderServiceNurseInfoMapper;
import com.blueocean_health.care.management.service.WorktableService;

/**
 * @Author ChenPeng cp
 * @Date 2017/8/24 17:29
 */

@Service
public class WorktableServiceImpl implements WorktableService{

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private NurseWorkerInfoMapper nurseWorkerInfoMapper;

    @Autowired
    private OrderServiceNurseInfoMapper orderServiceNurseInfoMapper;

    @Override
    public SysResult getListByHospitalIdForSort(String hospitalId) {
        if (hospitalId == null){
            return SysResult.error("param is null");
        }
        List<Department> list =  departmentMapper.getAllByHospitalIdForSort(hospitalId);
        if (list.size() < 1){
            return SysResult.ok("no query data");
        }
        return SysResult.ok().addData(list);
    }

    @Override
    @Transactional
    public SysResult updateSort(List<Department> list) throws OrderException{
        if (list.size() < 1){
            return SysResult.error("param is null");
        }
        int upFlag = 0;
        for (Department department:list) {
            upFlag = upFlag+departmentMapper.updateSortByid(department.getDeptId(),department.getSortNumber(),department.getIsShow());
        }
        if (upFlag == 0){
            return SysResult.error("update total : 0 ");
        }
        return SysResult.ok().addData(upFlag);
    }

    @Override
    public SysResult getWorkTableByHospital(String hospitalId,String clickDate) {

        if(hospitalId == null){
            return SysResult.error("No login information : hospitalId is null");
        }
        String nowDay = TimeUtils.getTime(TimeType.yyyy_MM_dd);
        if(clickDate == null || !TimeUtils.validate(clickDate, TimeType.yyyy_MM_dd)){
            clickDate = nowDay+" 00:00:00";
        }else{
            clickDate = clickDate+" 00:00:00";
        }
        Date checkDate = TimeUtils.getDateByString(clickDate,TimeType.yyyy_MM_dd_HH_mm_ss);
        Calendar end = Calendar.getInstance();
        end.setTime(checkDate);
        end.add(Calendar.DAY_OF_YEAR, 1);
        //String nextDate = TimeUtils.getStringByDate(end.getTime(),TimeType.yyyy_MM_dd_HH_mm_ss);

        List<WorkResultVo> result = new ArrayList<>();
        //所有非待岗护工列表
        List<WorkersVo> jobWorkers = new ArrayList<>();
        //根据医院找到所有科室
        List<Department> list = departmentMapper.getActiveByHospitalIdForSort(hospitalId);
        //根据所选择的时间和科室id找到所有符合的护工
        list.forEach(department -> {
            WorkResultVo workResultVo = new WorkResultVo();
            workResultVo.setDepartment(department.getDeptId());
            workResultVo.setDepartmentName(department.getDeptName());
            workResultVo.setDepartmentSort(department.getSortNumber());
            List<WorkersVo> workerVo =  orderServiceNurseInfoMapper.getWorkQueryVoByDeptId(workResultVo.getDepartment(), checkDate,end.getTime(),hospitalId);

            //过滤掉退款信息
            List<WorkersVo> passRefundVos = workerVo.stream().filter(workersVo -> {
                //如果全退，退款时间和原来的时间全覆盖，排除
                //留下没有退款信息的和没有全退款的

                Long refundStart = workersVo.getStime() == null ? 0 : workersVo.getStime().getTime();
                Long refundEnd = workersVo.getEtime() == null ? 0 : workersVo.getEtime().getTime();
                Long vostart = workersVo.getStartTime() == null ? 0 : workersVo.getStartTime().getTime();
                Long voend = workersVo.getEndTime() == null ? 0 : workersVo.getEndTime().getTime();
                Long paramStart = checkDate.getTime();
                Long paramEnd = end.getTime().getTime();

               return  (workersVo.getStime() == null && workersVo.getEtime() == null) ||
                       (refundStart.equals(vostart) && !refundEnd.equals(voend) && paramEnd > refundEnd) ||
                       (!refundStart.equals(vostart) && refundEnd.equals(voend) && paramStart < refundStart) ||
                       ((!refundStart.equals(vostart) && !refundEnd.equals(voend)) && (paramStart < refundStart || paramEnd > refundEnd))
                       ;
            }).collect(Collectors.toList());

            workResultVo.setWorkers(passRefundVos);
            result.add(workResultVo);
            jobWorkers.addAll(passRefundVos);
        });

        Set<Integer> jobworkIds = new HashSet<>();
        jobWorkers.forEach(workersVo -> jobworkIds.add(workersVo.getWorkerId()));
        List<WorkersVo> endTimeOfToday = orderServiceNurseInfoMapper.getWorksByOrderEndTimeOfToday(hospitalId);

        Set<Integer> workIdByOrderEndTimeOfToday = new HashSet<>();

        endTimeOfToday.forEach(vo -> {
            Long startTime =  vo.getStartTime().getTime();
            Long endTime =  vo.getEndTime().getTime();
            Long paramStart = checkDate.getTime();
            Long paramEnd = end.getTime().getTime();
            //如果没有退款信息，按照原来的逻辑判断时间是否在传参的范围内
            if (vo.getStime() == null && vo.getEtime() == null){
                if (endTime > paramStart && endTime <= paramEnd){
                    workIdByOrderEndTimeOfToday.add(vo.getId());
                }
            }else {
                Long stime =  vo.getStime().getTime();
                Long etime =  vo.getEtime().getTime();

                if (stime.equals(startTime) && !etime.equals(endTime) && endTime > paramStart && endTime <= paramEnd){
                    workIdByOrderEndTimeOfToday.add(vo.getId());
                }else if (etime.equals(endTime) && !stime.equals(startTime) && stime > paramStart && stime <= paramEnd){
                    workIdByOrderEndTimeOfToday.add(vo.getId());
                }else if (stime > startTime && etime < endTime ){
                    if ((stime > paramStart && stime <= paramEnd) || (endTime > paramStart && endTime <= paramEnd)){
                        workIdByOrderEndTimeOfToday.add(vo.getId());
                    }
                }else {
                    //排除
                }

            }

        });

        jobworkIds.retainAll(workIdByOrderEndTimeOfToday);
        //获取所有可用护工列表
        List<WorkersVo> allWorkers = nurseWorkerInfoMapper.getAllWorkersByHospitalId(hospitalId);
        Integer allNo = allWorkers.size();
        allWorkers.removeAll(jobWorkers);
        //待岗
        Integer laidOffNo = allWorkers.size();
        //上岗
        Integer mountGuardNo = allNo - laidOffNo;
        //今日下岗
        Integer outNo = jobworkIds.size();

        //set所有待岗护工
        result.forEach(workResultVo -> {
            if ("待岗".equals(workResultVo.getDepartmentName())) {
                workResultVo.setWorkers(allWorkers);
            }
        });

        return SysResult.ok().addData(result).addMsg(mountGuardNo + " "+outNo);
    }


    /*
     *导出excel报表
     * */
    @Override
    public List<WorkResultVo> getWorkTableByHospitalForExcel(String hospitalId,String clickDate) {
        List<WorkResultVo> result = new ArrayList<>();
        if(hospitalId == null){
            return result;
        }
        String nowDay = TimeUtils.getTime(TimeType.yyyy_MM_dd);
        if(clickDate == null || !TimeUtils.validate(clickDate, TimeType.yyyy_MM_dd)){
            clickDate = nowDay+" 00:00:00";
        }else{
            clickDate = clickDate+" 00:00:00";
        }
        Date checkDate = TimeUtils.getDateByString(clickDate,TimeType.yyyy_MM_dd_HH_mm_ss);
        Calendar end = Calendar.getInstance();
        end.setTime(checkDate);
        end.add(Calendar.DAY_OF_YEAR, 1);
        //所有非待岗护工列表
        List<WorkersVo> jobWorkers = new ArrayList<>();
        //根据医院找到所有科室
        List<Department> list = departmentMapper.getActiveByHospitalIdForSort(hospitalId);
        //根据所选择的时间和科室id找到所有符合的护工
        list.forEach(department -> {
            WorkResultVo workResultVo = new WorkResultVo();
            workResultVo.setDepartment(department.getDeptId());
            workResultVo.setDepartmentName(department.getDeptName());
            workResultVo.setDepartmentSort(department.getSortNumber());
            List<WorkersVo> workerVo =  orderServiceNurseInfoMapper.getWorkQueryVoByDeptId(workResultVo.getDepartment(), checkDate,end.getTime(),hospitalId);

            //过滤掉退款信息
            List<WorkersVo> passRefundVos = workerVo.stream().filter(workersVo -> {
                //如果全退，退款时间和原来的时间全覆盖，排除
                //留下没有退款信息的和没有全退款的
                Long refundStart = workersVo.getStime() == null ? 0 : workersVo.getStime().getTime();
                Long refundEnd = workersVo.getEtime() == null ? 0 : workersVo.getEtime().getTime();
                Long vostart = workersVo.getStartTime() == null ? 0 : workersVo.getStartTime().getTime();
                Long voend = workersVo.getEndTime() == null ? 0 : workersVo.getEndTime().getTime();
                Long paramStart = checkDate.getTime();
                Long paramEnd = end.getTime().getTime();

                return  (workersVo.getStime() == null && workersVo.getEtime() == null) ||
                        (refundStart.equals(vostart) && !refundEnd.equals(voend) && paramEnd > refundEnd) ||
                        (!refundStart.equals(vostart) && refundEnd.equals(voend) && paramStart < refundStart) ||
                        ((!refundStart.equals(vostart) && !refundEnd.equals(voend)) && (paramStart < refundStart || paramEnd > refundEnd))
                        ;
            }).collect(Collectors.toList());

            workResultVo.setWorkers(passRefundVos);
            result.add(workResultVo);
            jobWorkers.addAll(passRefundVos);
        });

        //获取所有可用护工列表
        List<WorkersVo> allWorkers = nurseWorkerInfoMapper.getAllWorkersByHospitalId(hospitalId);
        allWorkers.removeAll(jobWorkers);
        //set所有待岗护工
        result.forEach(workResultVo -> {
            if ("待岗".equals(workResultVo.getDepartmentName())) {
                workResultVo.setWorkers(allWorkers);
            }
        });
        return result;
    }



}
